package framework.utils
{
import com.hurlant.crypto.Crypto;
import com.hurlant.crypto.symmetric.ICipher;
import com.hurlant.crypto.symmetric.IPad;
import com.hurlant.crypto.symmetric.NullPad;
import com.hurlant.crypto.symmetric.PKCS5;
import com.hurlant.util.Base64;
import com.hurlant.util.Hex;

import flash.errors.IllegalOperationError;
import flash.utils.ByteArray;

/**
 * SecureUtil
 * @author jliang
 *
 */
public class SecureUtil
{
	
	public static function encrypt(input:String, 
														 key:String,  
														 zip:Boolean = true,
														 algorithm:String = "aes-cbc", 
														 padding:String = "None"):String
	{		
		while (key.length < 16)
		{
			key += " ";
		}
		
		var data:ByteArray = Hex.toArray(Hex.fromString(input)); 		
		if (zip) data.compress();
		data.position = 0;
		
		var crc:CRC32 = new CRC32();
		
		var by:ByteArray = new ByteArray();
		by.writeMultiByte(input, "utf-8");
		by.position = 0;
		
		crc.update(by);
		
		var head:String = "ok," + (zip ? 1 : 0) + "," + data.length + "," + crc.getValue();		
		
		while (head.length < 32)
		{
			head += " ";
		}
		
		var headBy:ByteArray = new ByteArray();
		headBy.writeMultiByte(head, "utf-8");
		
		headBy.position = headBy.length;		
		headBy.writeBytes(data);
		headBy.position = 0;
		
		data = headBy;
		
		var kdata:ByteArray = Hex.toArray(Hex.fromString(key));
		var pad:IPad = padding == "pkcs5" ? new PKCS5 : new NullPad; 
		var mode:ICipher = Crypto.getCipher("simple-" + algorithm, kdata, pad); 
		pad.setBlockSize(mode.getBlockSize()); 
		mode.encrypt(data); 
		return Base64.encodeByteArray(data); 
	}
	
	public static function decrypt(input:ByteArray, 
														 key:String,  
														 zip:Boolean = true,
														 algorithm:String = "aes-cbc", 
														 padding:String = "None"):String
	{		
		while (key.length < 16)
		{
			key += " ";
		}
		input.position = 0;
		
		var kdata:ByteArray = Hex.toArray(Hex.fromString(key));
		var pad:IPad = padding == "pkcs5" ? new PKCS5 : new NullPad; 
		var mode:ICipher = Crypto.getCipher("simple-" + algorithm, kdata, pad); 
		pad.setBlockSize(mode.getBlockSize()); 
		mode.decrypt(input); 
		
		input.position = 0;
		var headBy:ByteArray = new ByteArray();
		input.readBytes(headBy, 0, 32);
		headBy.position = 0;
		
		var content:ByteArray = new ByteArray();		
		input.position = 32;
		input.readBytes(content);
		content.position = 0;		
		
		var head:String = headBy.readMultiByte(headBy.bytesAvailable, "utf-8");
		
		var params:Array = head.split(",");
		if (params[0] != "ok")
		{
			throw new IllegalOperationError("数据加/解失败!");
		}
		
		if (params[1] == "1")
		{
			content.uncompress();
		}
		
		return Hex.toString(Hex.fromArray(content));
	}
}
}